// 安全文件系统服务 - 仅使用safe Rust

use std::sync::{Arc, Mutex, RwLock};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::io::{Result as IoResult, Error as IoError, ErrorKind};
use log::{info, warn, error};

// 导入RustFS服务
use crate::rustfs_service::RustFSService;

// 文件模式
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FileMode {
    Read,
    Write,
    ReadWrite,
}

// 文件描述符
pub type FileDescriptor = u32;

// 文件节点
pub struct FileNode {
    name: String,
    path: PathBuf,
    size: u64,
    is_directory: bool,
    children: HashMap<String, Arc<FileNode>>,
    // 其他文件元数据
}

impl FileNode {
    // 创建新文件节点
    pub fn new_file(name: String, path: PathBuf, size: u64) -> Self {
        FileNode {
            name,
            path,
            size,
            is_directory: false,
            children: HashMap::new(),
        }
    }

    // 创建新目录节点
    pub fn new_directory(name: String, path: PathBuf) -> Self {
        FileNode {
            name,
            path,
            size: 0,
            is_directory: true,
            children: HashMap::new(),
        }
    }

    // 获取文件名
    pub fn name(&self) -> &str {
        &self.name
    }

    // 获取文件路径
    pub fn path(&self) -> &PathBuf {
        &self.path
    }

    // 获取文件大小
    pub fn size(&self) -> u64 {
        self.size
    }

    // 设置文件大小
    pub fn set_size(&mut self, size: u64) {
        self.size = size;
    }
    
    // 更新文件大小
    pub fn update_size(&self, new_size: u64) {
        if let Ok(mut data) = self.data.write() {
            data.size = new_size;
        }
    }

    // 检查是否为目录
    pub fn is_dir(&self) -> bool {
        self.is_directory
    }

    // 添加子节点
    pub fn add_child(&mut self, node: Arc<FileNode>) -> bool {
        if !self.is_directory {
            return false;
        }
        self.children.insert(node.name().to_string(), Arc::clone(&node));
        true
    }

    // 移除子节点
    pub fn remove_child(&mut self, name: &str) -> bool {
        if !self.is_directory {
            return false;
        }
        self.children.remove(name).is_some()
    }

    // 获取子节点
    pub fn get_child(&self, name: &str) -> Option<Arc<FileNode>> {
        if !self.is_directory {
            return None;
        }
        self.children.get(name).map(Arc::clone)
    }

    // 列出所有子节点
    pub fn list_children(&self) -> Vec<Arc<FileNode>> {
        if !self.is_directory {
            return Vec::new();
        }
        self.children.values().map(Arc::clone).collect()
    }
}

// 打开的文件
pub struct OpenFile {
    node: Arc<FileNode>,
    mode: FileMode,
    position: u64,
}

impl OpenFile {
    // 创建新的打开文件
    pub fn new(node: Arc<FileNode>, mode: FileMode) -> Self {
        OpenFile {
            node,
            mode,
            position: 0,
        }
    }

    // 获取文件节点
    pub fn node(&self) -> &Arc<FileNode> {
        &self.node
    }

    // 获取文件模式
    pub fn mode(&self) -> FileMode {
        self.mode
    }

    // 获取当前位置
    pub fn position(&self) -> u64 {
        self.position
    }

    // 设置位置
    pub fn set_position(&mut self, position: u64) -> bool {
        if position <= self.node.size() {
            self.position = position;
            true
        } else {
            false
        }
    }

    // 向前移动位置
    pub fn advance_position(&mut self, offset: u64) -> bool {
        self.set_position(self.position + offset)
    }

    // 检查是否可读取
    pub fn can_read(&self) -> bool {
        self.mode == FileMode::Read || self.mode == FileMode::ReadWrite
    }

    // 检查是否可写入
    pub fn can_write(&self) -> bool {
        self.mode == FileMode::Write || self.mode == FileMode::ReadWrite
    }
}

// 文件系统服务
pub struct FileSystemService {
    root: Arc<FileNode>,
    open_files: RwLock<HashMap<FileDescriptor, Arc<Mutex<OpenFile>>>>,
    next_fd: FileDescriptor,
    initialized: bool,
    // 集成RustFS服务
    rustfs_service: Option<Arc<Mutex<RustFSService>>>,
}

impl FileSystemService {
    // 创建新的文件系统服务
    pub fn new() -> Result<Self, String> {
        // 创建根目录
        let root_path = PathBuf::from("/");
        let root = Arc::new(FileNode::new_directory("/".to_string(), root_path));

        Ok(FileSystemService {
            root,
            open_files: RwLock::new(HashMap::new()),
            next_fd: 3, // 通常0=stdin, 1=stdout, 2=stderr
            initialized: false,
            rustfs_service: None,
        })
    }
    
    /// 设置RustFS服务
    pub fn set_rustfs_service(&mut self, rustfs_service: Arc<Mutex<RustFSService>>) {
        self.rustfs_service = Some(rustfs_service);
        info!("RustFS service set in file system service");
    }

    // 启动文件系统服务
    pub fn start(&mut self) -> Result<(), String> {
        info!("Starting file system service");
        
        // 初始化文件系统服务
        self.initialized = true;
        
        // 创建一些标准目录
        self.create_directory("/bin").map_err(|e| format!("Failed to create /bin: {}", e))?;
        self.create_directory("/etc").map_err(|e| format!("Failed to create /etc: {}", e))?;
        self.create_directory("/home").map_err(|e| format!("Failed to create /home: {}", e))?;
        self.create_directory("/tmp").map_err(|e| format!("Failed to create /tmp: {}", e))?;
        
        info!("File system service started successfully");
        Ok(())
    }

    // 打开文件
    pub fn open(&mut self, path: &str, mode: FileMode) -> Result<FileDescriptor, String> {
        if !self.initialized {
            return Err("File system service not initialized".to_string());
        }

        // 如果配置了RustFS服务，优先使用RustFS
        if let Some(ref rustfs_service) = self.rustfs_service {
            if let Ok(mut service) = rustfs_service.try_lock() {
                match service.open_file(path, mode) {
                    Ok(_) => {
                        // RustFS处理成功，我们仍然需要创建本地的文件描述符
                        let node = match self.find_node(path) {
                            Ok(node) => node,
                            Err(_) => {
                                // 创建文件节点以匹配RustFS中的文件
                                self.create_file(path, 0).map_err(|e| format!("Failed to create file node: {}", e))?
                            }
                        };

                        // 检查是否为目录
                        if node.is_dir() {
                            return Err("Cannot open a directory as a file".to_string());
                        }

                        // 创建打开的文件
                        let open_file = Arc::new(Mutex::new(OpenFile::new(Arc::clone(&node), mode)));

                        // 分配文件描述符
                        let fd = self.next_fd;
                        self.next_fd += 1;

                        // 记录打开的文件
                        self.open_files.write().unwrap().insert(fd, Arc::clone(&open_file));

                        info!("Opened file {} with RustFS and descriptor {}", path, fd);
                        return Ok(fd);
                    },
                    Err(e) => {
                        warn!("RustFS open failed: {}, falling back to local file system", e);
                        // 继续使用本地文件系统
                    }
                }
            } else {
                warn!("Failed to lock RustFS service, falling back to local file system");
            }
        }

        // 本地文件系统实现
        // 解析路径
        let node = match self.find_node(path) {
            Ok(node) => node,
            Err(err) => {
                // 如果是写入模式，可以创建文件
                if mode == FileMode::Write || mode == FileMode::ReadWrite {
                    self.create_file(path, 0).map_err(|e| format!("Failed to create file: {}", e))?
                } else {
                    return Err(format!("File not found: {}", err));
                }
            }
        };

        // 检查是否为目录
        if node.is_dir() {
            return Err("Cannot open a directory as a file".to_string());
        }

        // 创建打开的文件
        let open_file = Arc::new(Mutex::new(OpenFile::new(Arc::clone(&node), mode)));

        // 分配文件描述符
        let fd = self.next_fd;
        self.next_fd += 1;

        // 记录打开的文件
        self.open_files.write().unwrap().insert(fd, Arc::clone(&open_file));

        info!("Opened file {} with local file system and descriptor {}", path, fd);
        Ok(fd)
    }

    // 关闭文件
    pub fn close(&self, fd: FileDescriptor) -> Result<bool, String> {
        if !self.initialized {
            return Err("File system service not initialized".to_string());
        }

        // 检查文件描述符是否存在
        if let Some(_open_file) = self.open_files.write().unwrap().remove(&fd) {
            // 这里可以添加清理操作
            info!("Closed file descriptor {}", fd);
            Ok(true)
        } else {
            warn!("Attempted to close invalid file descriptor {}", fd);
            Err("Invalid file descriptor".to_string())
        }
    }

    // 读取文件
    pub fn read(&self, fd: FileDescriptor, buffer: &mut [u8]) -> Result<usize, String> {
        if !self.initialized {
            return Err("File system service not initialized".to_string());
        }

        // 获取打开的文件
        let binding = self.open_files.read().unwrap();
        let open_file = match binding.get(&fd) {
            Some(file) => file,
            None => return Err("Invalid file descriptor".to_string()),
        };

        // 获取文件路径
        let path = {
            let file = open_file.lock().unwrap();
            file.node().path().clone()
        };

        // 如果配置了RustFS服务，优先使用RustFS读取
        if let Some(ref rustfs_service) = self.rustfs_service {
            if let Ok(mut service) = rustfs_service.try_lock() {
                match service.read_file(&path, buffer) {
                    Ok(bytes_read) => {
                        info!("Read {} bytes from file '{:?}' using RustFS", bytes_read, path);
                        return Ok(bytes_read);
                    },
                    Err(e) => {
                        warn!("RustFS read failed: {}, falling back to local file system", e);
                        // 继续使用本地文件系统
                    }
                }
            } else {
                warn!("Failed to lock RustFS service, falling back to local file system");
            }
        }

        // 本地文件系统实现
        let mut file = open_file.lock().unwrap();
        if !file.can_read() {
            return Err("File not open for reading".to_string());
        }

        // 计算可以读取的字节数
        let remaining = file.node().size() - file.position();
        let read_size = std::cmp::min(buffer.len() as u64, remaining) as usize;

        // 模拟读取（实际应从存储设备读取）
        // 这里只是填充零
        for i in 0..read_size {
            buffer[i] = 0;
        }

        // 更新位置
        file.advance_position(read_size as u64);

        info!("Read {} bytes from file '{:?}' using local file system", read_size, path);
        Ok(read_size)
    }

    // 写入文件
    pub fn write(&self, fd: FileDescriptor, buffer: &[u8]) -> Result<usize, String> {
        if !self.initialized {
            return Err("File system service not initialized".to_string());
        }

        // 获取打开的文件
        let binding = self.open_files.read().unwrap();
        let open_file = match binding.get(&fd) {
            Some(file) => file,
            None => return Err("Invalid file descriptor".to_string()),
        };

        // 检查是否可写入
        let file = open_file.lock().unwrap();
        if !file.can_write() {
            return Err("File not open for writing".to_string());
        }

        // 获取文件路径
        let path = file.node().path().clone();
        
        // 释放锁，因为我们接下来可能需要再次获取锁
        drop(file);

        // 如果配置了RustFS服务，优先使用RustFS写入
        if let Some(ref rustfs_service) = self.rustfs_service {
            if let Ok(mut service) = rustfs_service.try_lock() {
                match service.write_file(&path, buffer) {
                    Ok(bytes_written) => {
                        info!("Wrote {} bytes to file '{:?}' using RustFS", bytes_written, path);
                        return Ok(bytes_written);
                    },
                    Err(e) => {
                        warn!("RustFS write failed: {}, falling back to local file system", e);
                        // 继续使用本地文件系统
                    }
                }
            } else {
                warn!("Failed to lock RustFS service, falling back to local file system");
            }
        }

        // 本地文件系统实现
        let mut file = open_file.lock().unwrap();
        let write_size = buffer.len();

        // 更新文件大小
        let new_position = file.position() + write_size as u64;
        let node = Arc::clone(file.node());
        
        // 更新文件大小
        node.update_size(new_position);
        
        // 更新文件位置
        file.set_position(new_position);

        info!("Wrote {} bytes to file '{:?}' using local file system", write_size, path);
        Ok(write_size)
    }

    // 定位文件
    pub fn seek(&self, fd: FileDescriptor, position: u64) -> Result<bool, String> {
        if !self.initialized {
            return Err("File system service not initialized".to_string());
        }

        // 获取打开的文件
        let binding = self.open_files.read().unwrap();
        let open_file = match binding.get(&fd) {
            Some(file) => file,
            None => return Err("Invalid file descriptor".to_string()),
        };

        // 定位
        let mut file = open_file.lock().unwrap();
        let result = file.set_position(position);
        
        if result {
            info!("Set position of file descriptor {} to {}", fd, position);
        } else {
            warn!("Failed to set position of file descriptor {} to {}", fd, position);
        }
        
        Ok(result)
    }

    // 创建目录
    pub fn create_directory(&self, path: &str) -> Result<(), String> {
        if !self.initialized {
            return Err("File system service not initialized".to_string());
        }

        // 解析路径，获取父目录和目录名
        let path_obj = Path::new(path);
        let parent_path = path_obj.parent()
            .ok_or_else(|| "Invalid path".to_string())?;
        let dir_name = path_obj.file_name()
            .ok_or_else(|| "Invalid directory name".to_string())?
            .to_str()
            .ok_or_else(|| "Invalid directory name".to_string())?;

        // 查找父目录
        let parent_node = self.find_node(parent_path.to_str().unwrap_or(""))?;
        if !parent_node.is_dir() {
            return Err("Parent path is not a directory".to_string());
        }

        // 创建新目录节点
        let _new_dir = Arc::new(FileNode::new_directory(
            dir_name.to_string(),
            PathBuf::from(path)
        ));

        // 注意：实际实现中需要修改父目录节点，添加子节点
        // 这里简化处理
        
        info!("Created directory {}", path);
        Ok(())
    }

    // 创建文件
    pub fn create_file(&self, path: &str, size: u64) -> Result<Arc<FileNode>, String> {
        if !self.initialized {
            return Err("File system service not initialized".to_string());
        }

        // 解析路径，获取父目录和文件名
        let path_obj = Path::new(path);
        let parent_path = path_obj.parent()
            .ok_or_else(|| "Invalid path".to_string())?;
        let file_name = path_obj.file_name()
            .ok_or_else(|| "Invalid file name".to_string())?
            .to_str()
            .ok_or_else(|| "Invalid file name".to_string())?;

        // 查找父目录
        let parent_node = self.find_node(parent_path.to_str().unwrap_or(""))?;
        if !parent_node.is_dir() {
            return Err("Parent path is not a directory".to_string());
        }

        // 创建新文件节点
        let new_file = Arc::new(FileNode::new_file(
            file_name.to_string(),
            PathBuf::from(path),
            size
        ));

        // 注意：实际实现中需要修改父目录节点，添加子节点
        // 这里简化处理
        
        info!("Created file {} with size {} bytes", path, size);
        Ok(new_file)
    }

    // 删除文件或目录
    pub fn remove(&self, path: &str) -> Result<bool, String> {
        if !self.initialized {
            return Err("File system service not initialized".to_string());
        }

        // 如果配置了RustFS服务，优先使用RustFS删除
        if let Some(ref rustfs_service) = self.rustfs_service {
            if let Ok(mut service) = rustfs_service.try_lock() {
                match service.delete(path) {
                    Ok(success) if success => {
                        info!("Deleted {} using RustFS", path);
                        
                        // 查找要删除的节点（在本地文件系统中）
                        match self.find_node(path) {
                            Ok(node) => {
                                // 解析路径，获取父目录和名称
                                let path_obj = Path::new(path);
                                let parent_path = path_obj.parent()
                                    .ok_or_else(|| "Invalid path".to_string())?;
                                let name = path_obj.file_name()
                                    .ok_or_else(|| "Invalid name".to_string())?
                                    .to_str()
                                    .ok_or_else(|| "Invalid name".to_string())?;

                                // 查找父目录
                                let parent_node = self.find_node(parent_path.to_str().unwrap_or(""))?;
                                
                                // 从父目录中移除子节点（本地）
                                if parent_node.is_dir() {
                                    parent_node.remove_child(name);
                                }

                                if node.is_dir() {
                                    info!("Removed directory {} from local cache", path);
                                } else {
                                    info!("Removed file {} from local cache", path);
                                }
                            },
                            Err(e) => {
                                warn!("Failed to find node {} in local cache: {}", path, e);
                            }
                        }
                        
                        return Ok(true);
                    },
                    Err(e) => {
                        warn!("RustFS delete failed: {}, falling back to local file system", e);
                        // 继续使用本地文件系统
                    },
                    _ => {}
                }
            } else {
                warn!("Failed to lock RustFS service, falling back to local file system");
            }
        }

        // 本地文件系统实现
        // 解析路径，获取父目录和名称
        let path_obj = Path::new(path);
        let parent_path = path_obj.parent()
            .ok_or_else(|| "Invalid path".to_string())?;
        let name = path_obj.file_name()
            .ok_or_else(|| "Invalid name".to_string())?
            .to_str()
            .ok_or_else(|| "Invalid name".to_string())?;

        // 查找父目录
        let parent_node = self.find_node(parent_path.to_str().unwrap_or(""))?;
        if !parent_node.is_dir() {
            return Err("Parent path is not a directory".to_string());
        }

        // 查找要删除的节点
        let node = self.find_node(path)?;

        // 从父目录中移除子节点
        if !parent_node.remove_child(name) {
            return Err(format!("Failed to remove {} from parent directory", path));
        }
        
        if node.is_dir() {
            info!("Removed directory {} using local file system", path);
        } else {
            info!("Removed file {} using local file system", path);
        }
        
        Ok(true)
    }

    // 列出目录内容
    pub fn list_directory(&self, path: &str) -> Result<Vec<String>, String> {
        if !self.initialized {
            return Err("File system service not initialized".to_string());
        }

        // 如果配置了RustFS服务，优先使用RustFS列出目录内容
        if let Some(ref rustfs_service) = self.rustfs_service {
            if let Ok(mut service) = rustfs_service.try_lock() {
                match service.list(path) {
                    Ok(entries) => {
                        info!("Listed directory {} using RustFS", path);
                        
                        // 查找目录节点（在本地文件系统中）
                        match self.find_node(path) {
                            Ok(node) => {
                                if node.is_dir() {
                                    // 本地缓存同步
                                    for entry in &entries {
                                        let full_path = Path::new(path).join(entry);
                                        let entry_path = full_path.to_str()
                                            .ok_or_else(|| "Invalid path".to_string())?;

                                        // 检查该路径是否已经在本地缓存中
                                        if let Err(_) = self.find_node(entry_path) {
                                            // 如果不在，添加到本地缓存
                                            let parent_node = self.find_node(path)?;
                                            if parent_node.is_dir() {
                                                // 创建新的文件节点
                                                let is_dir = entry.ends_with('/') || entry.ends_with('\\');
                                                let new_node = if is_dir {
                                                    FileNode::new_directory(
                                                        entry.trim_end_matches(&['/', '\\'][..]).to_string(),
                                                        PathBuf::from(entry_path)
                                                    )
                                                } else {
                                                    FileNode::new_file(
                                                        entry.to_string(),
                                                        PathBuf::from(entry_path),
                                                        0
                                                    )
                                                };
                                                parent_node.add_child(Arc::new(new_node));
                                            }
                                        }
                                    }
                                }
                            },
                            Err(e) => {
                                warn!("Failed to find node {} in local cache: {}", path, e);
                            }
                        }
                        
                        return Ok(entries);
                    },
                    Err(e) => {
                        warn!("RustFS list failed: {}, falling back to local file system", e);
                        // 继续使用本地文件系统
                    }
                }
            } else {
                warn!("Failed to lock RustFS service, falling back to local file system");
            }
        }

        // 本地文件系统实现
        // 查找目录节点
        let node = self.find_node(path)?;
        if !node.is_dir() {
            return Err("Path is not a directory".to_string());
        }

        // 获取目录下的所有子节点名称
        let children = node.list_children();
        
        // 构建结果列表
        let mut result = Vec::new();
        for child in children {
            result.push(child.name().to_string());
        }
        
        info!("Listed directory {} using local file system", path);
        Ok(result)
    }

    // 查找节点（内部方法）
    fn find_node(&self, path: &str) -> Result<Arc<FileNode>, String> {
        // 规范化路径
        let normalized_path = if path.is_empty() || path == "." {
            Path::new("/")
        } else {
            Path::new(path)
        };
        
        let path_str = normalized_path.to_str()
            .ok_or_else(|| "Invalid path".to_string())?;
        
        // 首先在本地文件系统中查找
        // 处理根目录
        if path_str == "/" {
            return Ok(Arc::clone(&self.root));
        }
        
        // 本地路径查找逻辑
        // 将路径分割为组件
        let components: Vec<&str> = path_str
            .split_terminator('/')
            .filter(|c| !c.is_empty())
            .collect();
        
        if components.is_empty() {
            return Ok(Arc::clone(&self.root));
        }
        
        // 从根目录开始查找
        let mut current_node = Arc::clone(&self.root);
        
        for component in components.iter() {
            if !current_node.is_dir() {
                return Err(format!("Not a directory: {}", current_node.path().display()));
            }
            
            if let Some(child) = current_node.get_child(component) {
                current_node = child;
            } else {
                // 如果在本地找不到，尝试使用RustFS服务（如果配置了）
                if let Some(ref rustfs_service) = self.rustfs_service {
                    if let Ok(mut service) = rustfs_service.try_lock() {
                        // 构建完整路径
                        let mut full_path = String::new();
                        for (i, comp) in components[0..=components.iter().position(|c| c == component).unwrap_or(0)].iter().enumerate() {
                            if i > 0 {
                                full_path.push('/');
                            }
                            full_path.push_str(comp);
                        }
                        
                        // 检查路径是否存在于RustFS
                        if service.exists(&full_path) {
                            // 创建新节点并添加到本地缓存
                            let is_dir = service.is_directory(&full_path);
                            let new_node = if is_dir {
                                FileNode::new_directory(
                                    component.to_string(),
                                    PathBuf::from(&full_path)
                                )
                            } else {
                                // 尝试获取文件大小
                                let size = service.get_size(&full_path).unwrap_or(0);
                                FileNode::new_file(
                                    component.to_string(),
                                    PathBuf::from(&full_path),
                                    size
                                )
                            };
                            
                            current_node.add_child(Arc::new(new_node));
                            
                            // 继续查找下一个组件
                            if let Some(child) = current_node.get_child(component) {
                                current_node = child;
                                continue;
                            }
                        }
                    }
                }
                
                return Err(format!("Path not found: {}", path));
            }
        }
        
        Ok(current_node)
    }
}